<!DOCTYPE html>
<html lang="zh">

<head>
	<meta charset="UTF-8">
	<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
	<meta name="keywords" content="dromara.org" />
	<meta name="description" content="dromara.org" />
	<!-- 网页标签标题 -->
	<title>dromara(Open source organization)</title>
	<link rel="shortcut icon" href="/website/img/docsite.ico"/>
	<link rel="stylesheet" href="/website/build/documentation.css" />
</head>
<body>
	<div id="root"><div class="documentation-page" data-reactroot=""><header class="header-container header-container-normal"><div class="header-body"><a href="/website/zh-cn/index.html"><img class="logo" src="/website/img/dromara.png"/></a><div class="search search-normal"><span class="icon-search"></span></div><span class="language-switch language-switch-normal">En</span><div class="header-menu"><img class="header-menu-toggle" src="/website/img/system/menu_gray.png"/><ul><li class="menu-item menu-item-normal"><a href="/website/zh-cn/index.html" target="_self">首页</a><div class="sub-menu"><ul></ul></div></li><li class="menu-item menu-item-normal menu-item-normal-active"><a href="#">文档</a><div class="sub-menu"><ul><li><a href="/website/zh-cn/docs/soul/soul.html" target="_self">Soul</a></li><li><a href="/website/zh-cn/docs/hmily/index.html" target="_self">Hmily</a></li></ul></div></li><li class="menu-item menu-item-normal"><a href="/website/zh-cn/blog/index.html" target="_self">博客</a><div class="sub-menu"><ul></ul></div></li><li class="menu-item menu-item-normal"><a href="/website/zh-cn/community/index.html" target="_self">社区</a><div class="sub-menu"><ul></ul></div></li></ul></div></div></header><section class="content-section"><div class="sidemenu" id="menu"><div class="sidemenu-toggle"><img src="https://img.alicdn.com/tfs/TB1E6apXHGYBuNjy0FoXXciBFXa-200-200.png"/></div><ul><li class="menu-item menu-item-level-1"><span>Soul</span><ul><li style="height:36px;overflow:hidden" class="menu-item menu-item-level-2"><a href="/website/zh-cn/docs/soul/soul.html" target="_self">soul介绍</a></li><li style="height:36px;overflow:hidden" class="menu-item menu-item-level-2"><a href="/website/zh-cn/docs/soul/team.html" target="_self">团队介绍</a></li><li style="height:36px;overflow:hidden" class="menu-item menu-item-level-2"><a href="/website/zh-cn/docs/soul/induction.html" target="_self">soul极简入门</a></li><li style="height:36px;overflow:hidden" class="menu-item menu-item-level-2"><a href="/website/zh-cn/docs/soul/db.html" target="_self">数据库设计</a></li><li style="height:36px;overflow:hidden" class="menu-item menu-item-level-2"><a href="/website/zh-cn/docs/soul/config.html" target="_self">数据配置流程</a></li><li style="height:36px;overflow:hidden" class="menu-item menu-item-level-2"><a href="/website/zh-cn/docs/soul/dataSync.html" target="_self">数据同步原理</a></li><li style="height:36px;overflow:hidden" class="menu-item menu-item-level-2"><a href="/website/zh-cn/docs/soul/metaData.html" target="_self">元数据概念介绍</a></li><li style="height:792px;overflow:hidden" class="menu-item menu-item-level-2"><span>用户使用文档<img style="transform:rotate(0deg)" class="menu-toggle" src="/website/img/system/arrow_down.png"/></span><ul><li class="menu-item menu-item-level-3"><a href="/website/zh-cn/docs/soul/setup.html" target="_self">搭建soul网关环境</a></li><li class="menu-item menu-item-level-3"><a href="/website/zh-cn/docs/soul/soul-dict.html" target="_self">字典配置</a></li><li class="menu-item menu-item-level-3"><a href="/website/zh-cn/docs/soul/plugin-handle.html" target="_self">插件配置模板</a></li><li class="menu-item menu-item-level-3"><a href="/website/zh-cn/docs/soul/user-http.html" target="_self">http用户</a></li><li class="menu-item menu-item-level-3"><a href="/website/zh-cn/docs/soul/user-dubbo.html" target="_self">dubbo用户</a></li><li class="menu-item menu-item-level-3"><a href="/website/zh-cn/docs/soul/user-springcloud.html" target="_self">springCloud用户</a></li><li class="menu-item menu-item-level-3"><a href="/website/zh-cn/docs/soul/user-sofa.html" target="_self">sofa用户</a></li><li class="menu-item menu-item-level-3"><a href="/website/zh-cn/docs/soul/selector.html" target="_self">选择器规则详解</a></li><li class="menu-item menu-item-level-3"><a href="/website/zh-cn/docs/soul/user-dataSync.html" target="_self">数据同步策略</a></li><li class="menu-item menu-item-level-3"><a href="/website/zh-cn/docs/soul/plugin-divide.html" target="_self">divide插件</a></li><li class="menu-item menu-item-level-3"><a href="/website/zh-cn/docs/soul/plugin-dubbo.html" target="_self">dubbo插件</a></li><li class="menu-item menu-item-level-3"><a href="/website/zh-cn/docs/soul/plugin-springcloud.html" target="_self">spring cloud插件</a></li><li class="menu-item menu-item-level-3"><a href="/website/zh-cn/docs/soul/plugin-sofa.html" target="_self">sofa插件</a></li><li class="menu-item menu-item-level-3"><a href="/website/zh-cn/docs/soul/plugin-rateLimiter.html" target="_self">rateLimiter插件</a></li><li class="menu-item menu-item-level-3"><a href="/website/zh-cn/docs/soul/plugin-hystrix.html" target="_self">hystrix插件</a></li><li class="menu-item menu-item-level-3"><a href="/website/zh-cn/docs/soul/plugin-sentinel.html" target="_self">sentinel插件</a></li><li class="menu-item menu-item-level-3"><a href="/website/zh-cn/docs/soul/plugin-monitor.html" target="_self">monitor插件</a></li><li class="menu-item menu-item-level-3"><a href="/website/zh-cn/docs/soul/plugin-waf.html" target="_self">waf插件</a></li><li class="menu-item menu-item-level-3"><a href="/website/zh-cn/docs/soul/plugin-sign.html" target="_self">sign插件</a></li><li class="menu-item menu-item-level-3"><a href="/website/zh-cn/docs/soul/plugin-rewrite.html" target="_self">rewrite插件</a></li><li class="menu-item menu-item-level-3"><a href="/website/zh-cn/docs/soul/plugin-websocket.html" target="_self">websocket支持</a></li></ul></li><li style="height:360px;overflow:hidden" class="menu-item menu-item-level-2"><span>开发者文档<img style="transform:rotate(0deg)" class="menu-toggle" src="/website/img/system/arrow_down.png"/></span><ul><li class="menu-item menu-item-level-3"><a href="/website/zh-cn/docs/soul/dev-filter.html" target="_self">自定义filter</a></li><li class="menu-item menu-item-level-3"><a href="/website/zh-cn/docs/soul/dev-plugin.html" target="_self">自定义插件</a></li><li class="menu-item menu-item-level-3"><a href="/website/zh-cn/docs/soul/dev-file.html" target="_self">文件上传下载</a></li><li class="menu-item menu-item-level-3"><a href="/website/zh-cn/docs/soul/dev-iphost.html" target="_self">自定义解析IP与host</a></li><li class="menu-item menu-item-level-3"><a href="/website/zh-cn/docs/soul/dev-result.html" target="_self">自定义返回结果</a></li><li class="menu-item menu-item-level-3"><a href="/website/zh-cn/docs/soul/dev-sign.html" target="_self">自定义签名插件算法与验证</a></li><li class="menu-item menu-item-level-3"><a href="/website/zh-cn/docs/soul/dev-client.html" target="_self">多语言http客户端接入</a></li><li class="menu-item menu-item-level-3"><a href="/website/zh-cn/docs/soul/dev-thread.html" target="_self">线程模型</a></li><li class="menu-item menu-item-level-3"><a href="/website/zh-cn/docs/soul/dev-netty.html" target="_self">soul调优</a></li></ul></li><li style="height:144px;overflow:hidden" class="menu-item menu-item-level-2"><span>社区贡献<img style="transform:rotate(0deg)" class="menu-toggle" src="/website/img/system/arrow_down.png"/></span><ul><li class="menu-item menu-item-level-3"><a href="/website/zh-cn/docs/soul/contributor.html" target="_self">贡献者指南</a></li><li class="menu-item menu-item-level-3"><a href="/website/zh-cn/docs/soul/committer.html" target="_self">提交者指南</a></li><li class="menu-item menu-item-level-3"><a href="/website/zh-cn/docs/soul/code-conduct.html" target="_self">编码规范</a></li></ul></li></ul></li></ul></div><div class="doc-content markdown-body" id="doc-body"><h2>说明</h2>
<ul>
<li>本文是说明,如何进行 <code>org.springframework.web.server.WebFliter</code> 的扩展。</li>
</ul>
<h2>跨域支持</h2>
<ul>
<li>新增 <code>org.dromara.soul.bootstrap.cors.CrossFilter</code> 实现 WebFilter。</li>
</ul>
<pre><code class="language-java"><span class="hljs-keyword">public</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">CrossFilter</span> <span class="hljs-keyword">implements</span> <span class="hljs-title">WebFilter</span> </span>{

    <span class="hljs-keyword">private</span> <span class="hljs-keyword">static</span> <span class="hljs-keyword">final</span> String ALLOWED_HEADERS = <span class="hljs-string">"x-requested-with, authorization, Content-Type, Authorization, credential, X-XSRF-TOKEN,token,username,client"</span>;

    <span class="hljs-keyword">private</span> <span class="hljs-keyword">static</span> <span class="hljs-keyword">final</span> String ALLOWED_METHODS = <span class="hljs-string">"*"</span>;

    <span class="hljs-keyword">private</span> <span class="hljs-keyword">static</span> <span class="hljs-keyword">final</span> String ALLOWED_ORIGIN = <span class="hljs-string">"*"</span>;

    <span class="hljs-keyword">private</span> <span class="hljs-keyword">static</span> <span class="hljs-keyword">final</span> String ALLOWED_EXPOSE = <span class="hljs-string">"*"</span>;

    <span class="hljs-keyword">private</span> <span class="hljs-keyword">static</span> <span class="hljs-keyword">final</span> String MAX_AGE = <span class="hljs-string">"18000"</span>;

    <span class="hljs-meta">@Override</span>
    <span class="hljs-meta">@SuppressWarnings</span>(<span class="hljs-string">"all"</span>)
    <span class="hljs-function"><span class="hljs-keyword">public</span> Mono&lt;Void&gt; <span class="hljs-title">filter</span><span class="hljs-params">(<span class="hljs-keyword">final</span> ServerWebExchange exchange, <span class="hljs-keyword">final</span> WebFilterChain chain)</span> </span>{
        ServerHttpRequest request = exchange.getRequest();
        <span class="hljs-keyword">if</span> (CorsUtils.isCorsRequest(request)) {
            ServerHttpResponse response = exchange.getResponse();
            HttpHeaders headers = response.getHeaders();
            headers.add(<span class="hljs-string">"Access-Control-Allow-Origin"</span>, ALLOWED_ORIGIN);
            headers.add(<span class="hljs-string">"Access-Control-Allow-Methods"</span>, ALLOWED_METHODS);
            headers.add(<span class="hljs-string">"Access-Control-Max-Age"</span>, MAX_AGE);
            headers.add(<span class="hljs-string">"Access-Control-Allow-Headers"</span>, ALLOWED_HEADERS);
            headers.add(<span class="hljs-string">"Access-Control-Expose-Headers"</span>, ALLOWED_EXPOSE);
            headers.add(<span class="hljs-string">"Access-Control-Allow-Credentials"</span>, <span class="hljs-string">"true"</span>);
            <span class="hljs-keyword">if</span> (request.getMethod() == HttpMethod.OPTIONS) {
                response.setStatusCode(HttpStatus.OK);
                <span class="hljs-keyword">return</span> Mono.empty();
            }
        }
        <span class="hljs-keyword">return</span> chain.filter(exchange);
    }
}
</code></pre>
<ul>
<li>将 CrossFilter 注册成为 spring的bean,完事.</li>
</ul>
<h2>网关过滤 springboot健康检查</h2>
<ul>
<li>注意顺序，使用 <code>@Order</code> 注解</li>
</ul>
<pre><code class="language-java"><span class="hljs-meta">@Component</span>
<span class="hljs-meta">@Order</span>(-<span class="hljs-number">99</span>)
<span class="hljs-keyword">public</span> <span class="hljs-keyword">final</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">HealthFilter</span> <span class="hljs-keyword">implements</span> <span class="hljs-title">WebFilter</span> </span>{

    <span class="hljs-keyword">private</span> <span class="hljs-keyword">static</span> <span class="hljs-keyword">final</span> String[] FILTER_TAG = {<span class="hljs-string">"/actuator/health"</span>, <span class="hljs-string">"/health_check"</span>};

    <span class="hljs-meta">@Override</span>
    <span class="hljs-function"><span class="hljs-keyword">public</span> Mono&lt;Void&gt; <span class="hljs-title">filter</span><span class="hljs-params">(@Nullable <span class="hljs-keyword">final</span> ServerWebExchange exchange, @Nullable <span class="hljs-keyword">final</span> WebFilterChain chain)</span> </span>{
        ServerHttpRequest request = Objects.requireNonNull(exchange).getRequest();
        String urlPath = request.getURI().getPath();
        <span class="hljs-keyword">for</span> (String check : FILTER_TAG) {
            <span class="hljs-keyword">if</span> (check.equals(urlPath)) {
                String result = JsonUtils.toJson(<span class="hljs-keyword">new</span> Health.Builder().up().build());
                DataBuffer dataBuffer = exchange.getResponse().bufferFactory().wrap(result.getBytes());
                <span class="hljs-keyword">return</span> exchange.getResponse().writeWith(Mono.just(dataBuffer));
            }
        }
        <span class="hljs-keyword">return</span> Objects.requireNonNull(chain).filter(exchange);
    }
}

</code></pre>
<h2>继承 <code>org.dromara.soul.web.filter.AbstractWebFilter</code></h2>
<ul>
<li>
<p>新增一个类，继承它。</p>
</li>
<li>
<p>实现它的2个方法。</p>
</li>
</ul>
<pre><code class="language-java">   <span class="hljs-comment">/**
     * this is Template Method ,children Implement your own filtering logic.
     *
     * <span class="hljs-doctag">@param</span> exchange the current server exchange
     * <span class="hljs-doctag">@param</span> chain    provides a way to delegate to the next filter
     * <span class="hljs-doctag">@return</span> {<span class="hljs-doctag">@code</span> Mono&lt;Boolean&gt;} result：TRUE (is pass)，and flow next filter；FALSE (is not pass) execute doDenyResponse(ServerWebExchange exchange)
     */</span>
    <span class="hljs-function"><span class="hljs-keyword">protected</span> <span class="hljs-keyword">abstract</span> Mono&lt;Boolean&gt; <span class="hljs-title">doFilter</span><span class="hljs-params">(ServerWebExchange exchange, WebFilterChain chain)</span></span>;

    <span class="hljs-comment">/**
     * this is Template Method ,children Implement your own And response client.
     *
     * <span class="hljs-doctag">@param</span> exchange the current server exchange.
     * <span class="hljs-doctag">@return</span> {<span class="hljs-doctag">@code</span> Mono&lt;Void&gt;} response msg.
     */</span>
    <span class="hljs-function"><span class="hljs-keyword">protected</span> <span class="hljs-keyword">abstract</span> Mono&lt;Void&gt; <span class="hljs-title">doDenyResponse</span><span class="hljs-params">(ServerWebExchange exchange)</span></span>;
</code></pre>
<ul>
<li><code>doFilter</code> 方法返回 Mono<true> 表示通过,反之则不通过，不通过的时候，会调用 <code>doDenyResponse</code>,输出相关信息到前端。</li>
</ul>
</div></section><footer class="footer-container"><div class="footer-body"><img src="/website/img/dromara.png"/><div class="cols-container"><div class="col col-12"><h3>免责声明</h3><p>任何单位或个人转载本网站的所有相关信息，请注明来源。</p></div><div class="col col-6"><dl><dt>文档</dt><dd><a href="/website/zh-cn/docs/soul/soul.html" target="_self">概览</a></dd><dd><a href="/website/zh-cn/docs/soul/soul.html" target="_self">快速开始</a></dd><dd><a href="/website/zh-cn/docs/soul/soul.html" target="_self">开发者指南</a></dd></dl></div><div class="col col-6"><dl><dt>资源</dt><dd><a href="/website/zh-cn/blog/index.html" target="_self">博客</a></dd><dd><a href="/website/zh-cn/community/index.html" target="_self">社区</a></dd></dl></div></div><div class="copyright"><span>Copyright ©2020 xiaoyu@apache.org by xiaoyu</span></div></div></footer></div></div>
	<script src="https://f.alicdn.com/react/15.4.1/react-with-addons.min.js"></script>
	<script src="https://f.alicdn.com/react/15.4.1/react-dom.min.js"></script>
	<script>
		window.rootPath = '/website';
  </script>
	<script src="/website/build/documentation.js"></script>
</body>
</html>